package ca.polymtl.liom;
import java.io.File;
import java.io.IOException;
import java.lang.String;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import ca.polymtl.liom.fileio.*;
import ca.polymtl.liom.gui.LIOMExpStartDialog;

public abstract class LIOMMainExperiment {
	public final static Logger logger = Logger.getLogger(LIOMMainExperiment.class.getName());
	private String p_exp_folder;
	private String p_current_save_folder;
	private LIOMDirectoryNameSelector p_dir_selector;
	private Date p_time_start;
	private Date p_time_stop;
	protected LIOMInfoFileHandler p_info_file_hdlr;
	// TODO: Add last directory as app preferences for base_dir
	
	LIOMMainExperiment(){
		p_dir_selector = null;
	}
	
	public boolean setExperimentFolder(){
		try{
			LIOMExpStartDialog dlg = new LIOMExpStartDialog();
			dlg.setModal(true);
			dlg.setVisible(true);
			if( dlg.dataValid() ){
				p_exp_folder = dlg.getExpBaseFolder();				
				p_dir_selector = new LIOMDirectoryNameSelector(p_exp_folder,dlg.getExpShortName(),true);
				p_info_file_hdlr = new LIOMInfoFileHandler();
				String log_file = p_dir_selector.getBaseDir()+File.separator+"ResumeExp.txt";
				logger.addHandler(new FileHandler(log_file));
				LIOMMainExperiment.logger.setLevel(Level.FINE);
				logger.fine("Experiment Started");
				logger.fine("Directory: "+p_dir_selector.getBaseDir());
				logger.fine(dlg.getExpComments());
				return true;
			}
			else{
				return false;
			}
		}
		catch(IOException e){
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * Stub function that will be re-implemented in sub-classes of experiment. All 
	 * user interface and acquisition code is implemented in these sub-classes. Logging,
	 * experiment folder structure and naming is implemented in this class however to 
	 * uniformize acquisition across systems.
	 */
	public void runAcquisition(){
		
	}
	/**
	 * Stub function that will be re-implemented in sub-classes of experiment. All 
	 * user interface and acquisition code is implemented in these sub-classes. Logging,
	 * experiment folder structure and naming is implemented in this class however to 
	 * uniformize acquisition across systems.
	 */
	public void stopAcquisition(){
		
	}	
	/**
	 * 
	 * @return The current folder where data is saved.
	 */
	public String getCurrentSaveFolder(){
		return p_current_save_folder;
	}
	
	/**
	 * Called when the application starts saving. Sub-classes must implement their own 
	 * saving logic but directory creation, info.txt file and ResumeExp.txt file are 
	 * created here with basic info uniformly saved for all experiments.
	 */
	public final void startSaving(){
		p_current_save_folder = p_dir_selector.getNextFolder();
		p_info_file_hdlr.setCurrentDir(p_current_save_folder);
		p_info_file_hdlr.addHeader("Generic Experiment");
		
		p_time_start=new Date();
		DateFormat df=new SimpleDateFormat("HH:mm:ss");
		
		logger.fine("Starting: " + p_current_save_folder );
		logger.info("Time Start: "+df.format(p_time_start));
		

		onStartSaving();
	}
	
	/**
	 * Called when stopping recording in a given experiment. Time elapsed is computed
	 * and printed in ResumeExp. After each recording, the user is forced to enter comments
	 * or tag the scan as being not-good: in which case an option to delete all scans at the
	 * end will be offered.
	 */
	public final void stopSaving(){
		// TODO: Force inclusion of comments on scan, see where to save: info or resume
		p_info_file_hdlr.saveInfoFile();
		p_time_stop=new Date();
		long time_elapsed = (p_time_start.getTime()-p_time_stop.getTime())/1000;
		logger.info("Time Elapsed: "+String.format("%d", time_elapsed));
		onStopSaving();
	}
	
	/**
	 * This is a trick to force sub-classes to implement these and insure that
	 * the logic from startSaving and stopSaving remains executed for all sub-
	 * experiments. 
	 */
	protected abstract void onStartSaving();
	/**
	 * This is a trick to force sub-classes to implement these and insure that
	 * the logic from startSaving and stopSaving remains executed for all sub-
	 * experiments. 
	 */
	protected abstract void onStopSaving();

}
